package questions;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 多线程时，限制执行超时，比如10个线程，最多允许执行10s
 * <p>
 * 实现方式，使用{@link ExecutorService#invokeAll(Collection, long, TimeUnit)} 来指定等待时间。
 * 处理结果时要注意，{@link Future#get()}方法在获取没执行完的线程的结果时，会抛出Cancel的异常，可以通过{@link Future#isCancelled()}来做判断
 */
public class MultiThreadOverTimeDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        Callable<Integer> callable = new Callable<Integer>() {

            @Override
            public Integer call() throws Exception {
                Thread.sleep(2000);
                return 1;
            }
        };
        Set<Callable<Integer>> set = new HashSet<>();
        set.add(callable);
        set.add(() -> {
            Thread.sleep(1000);
            return 2;
        });
        try {
            List<Future<Integer>> excuteResult = executor.invokeAll(set, 1, TimeUnit.SECONDS);
            for (Future<Integer> future : excuteResult) {
                if (future.isCancelled()) {
                    System.out.println("someone was canceled");
                    continue;
                } else if (future.isDone()) {
                    System.out.println("Done:" + future.get());
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        executor.shutdown();

    }
}
